package lock

import (

	//"fmt"
	"runtime"
	//"sync/atomic"
	"sync"
	"time"
	"bytes"
	"strconv"
)

var now time.Time
func getGID() uint64 {
	b := make([]byte, 64)
	b = b[:runtime.Stack(b, false)]
	b = bytes.TrimPrefix(b, []byte("goroutine "))
	b = b[:bytes.IndexByte(b, ' ')]
	n, _ := strconv.ParseUint(string(b), 10, 64)
	return n
}
type TRWlocker struct {
	w, r        time.Time
	wpath       string
	rpath       string
	rlpath      []string
	rulpath     []string
	l           *sync.RWMutex
	dev         bool
	readerCount int32 // number of pending readers
	dur         time.Duration
	cb          func(str string)
}

var TimeNull = time.Time{}
//
//func NewTRWLocker(dev bool, dur time.Duration, cb func(str string)) *TRWlocker {
//	trw := new(TRWlocker)
//	trw.l = new(sync.RWMutex)
//	trw.r = TimeNull
//	trw.dur = dur
//	trw.cb = cb
//	trw.readerCount = 0
//	done := make(chan int, 0)
//	go trw.timetick(done)
//	<-done
//	fmt.Println("done")
//	return trw
//}
//
//func (this *TRWlocker) timetick(done chan int) {
//	now = time.Now()
//	done<-1
//	for true {
//		now = time.Now()
//		time.Sleep(2*time.Millisecond)
//	}
//}

//func (this *TRWlocker) Lock() {
//	_, file, line, _ := runtime.Caller(1)
//	this.wpath = fmt.Sprintf("PID[%d]:Lock Called by %s:%d", getGID(), file, line)
//	this.w = now
//	this.l.Lock()
//}
//func (this *TRWlocker) RCount() int32 {
//	return 	atomic.LoadInt32(&this.readerCount)
//
//}
//func (this *TRWlocker) Unlock() {
//	this.l.Unlock()
//	_, file, line, _ := runtime.Caller(1)
//	//if this.w.Add(this.dur).Before(now) {
//		if this.cb != nil {
//			this.cb(fmt.Sprintf("time cost %d from %s to %s ", (now.UnixNano() - this.w.UnixNano())/1000, this.wpath, fmt.Sprintf("Lock Called by %s:%d", file, line)))
//		}
//	//}
//}
//
//func (this *TRWlocker) RLock() {
//	//_, file, line, _ := runtime.Caller(1)
//	runtime.Caller(1)
//	if this.r == TimeNull {
//		this.r = now
//	}
//	//this.rlpath = append(this.rlpath, fmt.Sprintf("RLock Called by %s:%d at %s", file, line, now.Format(time.StampNano)))
//	atomic.AddInt32(&this.readerCount, 1)
//	this.l.RLock()
//}
//
//func (this *TRWlocker) RUnlock() {
//	this.l.RUnlock()
//	//_, file, line, _ := runtime.Caller(1)
//	runtime.Caller(1)
//
//	//this.rulpath = append(this.rulpath, fmt.Sprintf("RULock Called by %s:%d at %s", file, line, now.Format(time.StampNano)))
//	atomic.AddInt32(&this.readerCount, -1)
//	if this.readerCount == 0 {
//		//all reader lock release
//		if this.r != TimeNull && this.r.Add(this.dur).Before(now) {
//			if this.cb != nil {
//				str := "\n"
//				for k := 0; k < len(this.rlpath);k++ {
//					str +=this.rlpath[k]+ "\n"
//				}
//				for k := 0; k < len(this.rulpath);k++ {
//					str += this.rulpath[k] + "\n"
//				}
//				if this.cb != nil {
//					this.cb(str)
//				}
//			}
//		}
//		this.rulpath = []string{}
//		this.rlpath = []string{}
//		this.r = TimeNull
//	}
//}

func NewTRWLocker(dev bool, dur time.Duration, cb func(str string)) *TRWlocker {
	trw := new(TRWlocker)
	trw.l = new(sync.RWMutex)
	trw.r = TimeNull
	trw.dur = dur
	trw.cb = cb
	trw.readerCount = 0
	return trw
}

func (this *TRWlocker) Lock() {
	this.l.Lock()
}

func (this *TRWlocker) Unlock() {
	this.l.Unlock()

}

func (this *TRWlocker) RLock() {
	this.l.RLock()
}

func (this *TRWlocker) RUnlock() {
	this.l.RUnlock()

}